/**
 * @author - lhn
 * @version - 1.0.0
 * @description - 工具
 * @datetime - 2025/2/28
 * @editor - lhn
 */


import IUseTools from './IUseTools';

class Tools implements IUseTools {

  constructor() {
  }

  debounce(fun: Function, duration: number = 1000): Function {
    let timerId: any; // 记录上一次计时器Id

    return (...args: any[]): void => {
      if (timerId) {
        clearTimeout(timerId);
      }

      timerId = setTimeout((): void => {
        fun.apply(this, ...args);
      }, duration);
    };
  }

  throttle(fun: Function, delay: number = 1000) {
    let valid = true;
    return (...args: any[]) => {
      if (!valid) {
        return false;
      }

      valid = false;
      setTimeout(() => {
        fun.apply(this, args);
        valid = true;
      }, delay);
    };
  }

  deepCopy(obj: any) {
    // return JSON.parse(JSON.stringify(obj))

    if (!obj) return null;

    let objCopy: any = Array.isArray(obj) ? [] : {};

    if (typeof obj === 'object') {
      for (const key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          if (typeof obj[key] === 'object') {
            objCopy[key] = this.deepCopy(obj[key]);
          } else {
            objCopy[key] = obj[key];
          }
        }
      }
    } else {
      objCopy = obj;
    }

    return objCopy;
  }

  objCompare(obj1: any, obj2: any): boolean {

    if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;

    for (const key in obj1) {
      if (obj1.hasOwnProperty(key) !== obj2.hasOwnProperty(key)) return false;
      if (typeof obj1[key] !== typeof obj2[key]) return false;

      if (typeof obj1[key] === 'object') {
        if (!this.objCompare(obj1[key], obj2[key])) return false;
      } else {
        if (obj1[key] !== obj2[key]) return false;
      }
    }

    return true;
  }

  primeNumber(n: number): number[] {
    if (n <= 1) return []; // 0和1不是质数  
    let primes = [2]; // 2是最小的质数  
    for (let num = 3; num <= n; num += 2) { // 从3开始，步长为2，因为除了2以外的偶数都不是质数  
      let isPrime = true;
      for (let i = 2; i < primes.length; i++) {
        if (num % primes[i] === 0) {
          isPrime = false;
          break;
        }
        // 如果这个数已经被之前所有小于它的质数都除不尽，那么只需要检查到sqrt(num)即可  
        // 因为如果num有一个因子大于sqrt(num)，那么它必定还有一个小于或等于sqrt(num)的因子  
        // if (primes[i] * primes[i] > num) {
        //   break;
        // }
      }
      if (isPrime) {
        primes.push(num);
      }
    }
    return primes;
  }

  isPalindrome = (str: string): boolean => {
    let i = 0;
    let j = str.length - 1;
    while (i < j) {
      const left = str[i].toLowerCase();
      const right = str[j].toLowerCase();

      if (!(left >= 'a' && left <= 'z') || (left >= '0' && left <= '9')) {
        i++;
      } else if (!(right >= 'a' && right <= 'z') || (right >= '0' && right <= '9')) {
        j--;
      } else if (left === right) {
        i++;
        j--;
      } else {
        return false;
      }
    }

    return true;
  };

  * walk(version: string): Generator<string, void, unknown> {
    let part = '';
    let terminals: string[] = ['.', '-', '+']; // 终结符
    for (let i = 0; i < version.length; i++) {
      // 判断当前字符是包含终结符
      if (terminals.includes(version[i])) {
        yield part;
        part = '';
      } else {
        part += version[i];
      }
    }

    if (part) {
      yield part;
    }
  }
}

const useTools = new Tools();
export default useTools;